package com.cman777.springc.redis.util;

import com.cman777.springc.common.bean.exception.BusinessException;
import lombok.extern.log4j.Log4j2;
import org.redisson.api.RLock;

import javax.validation.constraints.NotBlank;
import java.util.concurrent.TimeUnit;

/**
 * @author chenzhicong
 * @time 2019/11/10 16:04
 * @description
 */
@Log4j2
public class RedisLockUtil {


    private static final String REDIS_LOCK_PREFIX = "LOCK_";

    /**
     *
     * @param rLock
     * @param waitTime
     * @param leaseTime
     */
    public static void lock(RLock rLock,long waitTime,long leaseTime) {
        try {
            if (!rLock.tryLock(waitTime,leaseTime, TimeUnit.SECONDS)) {
                log.error("请求redis锁超时，key:{},waitTime:{}",rLock.getName(),waitTime);
                throw new BusinessException("OVERTIME_WHEN_ACQUIRE_LOCK","操作失败");
            }
            log.info("获取redis锁成功,key:{},waitTime:{},leaseTime:{},threadId:{}",
                    rLock.getName(),waitTime,leaseTime,Thread.currentThread().getId());
        } catch (InterruptedException e) {
            log.error("获取redis锁失败:{}",e.getMessage());
            throw new BusinessException("ACQUIRE_LOCK_INTERRUPTED","操作失败");
        }
    }

    /**
     *
     * @param prefix
     * @param salt
     * @return LOCK_ + 自定义前缀 + _ + spel解析的盐
     */
    public static String packageRedissonLockKey(@NotBlank String prefix, @NotBlank String salt) {
        return REDIS_LOCK_PREFIX + prefix + "_" + salt;
    }
    /**
     *
     * @param rLock
     */
    public static void unlock(RLock rLock) {
        if (null != rLock) {
            if (rLock.isHeldByCurrentThread()) {
                rLock.unlock();
                log.info("释放redis锁成功,key:{}", rLock.getName());
            } else {
                log.info("当前锁不被当前线程持有,故不做解锁操作,key:{}", rLock.getName());
            }
        }
    }
}
